package com.pubinfo.passbook.common.service.aviator.impl;

import com.googlecode.aviator.*;
import com.googlecode.aviator.exception.ExpressionSyntaxErrorException;
import com.pubinfo.passbook.common.exception.ServiceException;
import com.pubinfo.passbook.common.service.aviator.AviatorScriptService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;

@Service
public class AviatorScriptServiceImpl implements AviatorScriptService {
  
  @Override
  public BigDecimal execute(String equation, String cacheKey, Map<String, Object> env) {
    
    // 创建解释器
    AviatorEvaluatorInstance engine = AviatorEvaluator.newInstance();
    // 打开跟踪执行
    engine.setOption(Options.ALWAYS_PARSE_INTEGRAL_NUMBER_INTO_DECIMAL, true);
    // AviatorEvaluator.validate(equation);
    Expression exp = engine.compile(equation, cacheKey, true);
    
    System.out.println(exp.execute(env));
    //System.out.println(exp.execute(exp.newEnv("score", 50)));
    
    return null;
  }
  
  @Override
  public BigDecimal execute(String equation, Map<String, Object> env) {
  
    // 创建解释器
    AviatorEvaluatorInstance engine = AviatorEvaluator.newInstance();
    // 打开跟踪执行
    // engine.setOption(Options.ALWAYS_PARSE_INTEGRAL_NUMBER_INTO_DECIMAL, true);
    engine.setOption(Options.TRACE_EVAL, true);
  
    validate(equation);
    Expression exp = engine.compile(equation);
    Object obj = exp.execute(env);
    if (obj instanceof Double || obj instanceof Integer || obj instanceof BigDecimal) {
      return new BigDecimal(obj.toString());
    }
    // System.out.println(exp.execute(env));
    return new BigDecimal(0);
  }
  
  @Override
  public BigDecimal executeNotNegativeNumber(String equation, Map<String, Object> env) {
    BigDecimal sum = execute(equation, env);
    if (sum.compareTo(BigDecimal.ZERO) != 1) {
      return BigDecimal.ZERO;
    }
    return sum;
  }
  
  @Override
  public Boolean validate(String equation) {
    try {
      AviatorEvaluator.validate(equation);
    } catch (ExpressionSyntaxErrorException e) {
      
      throw new ServiceException("语法错误：" + e.getMessage());
      
    }
    return true;
  }
}
